home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / slip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  3.9 KB  |  186 lines

  1. /* Send and receive IP datagrams on serial lines. Compatible with SLIP
  2.  * under Berkeley Unix.
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "config.h"
  7. #include "mbuf.h"
  8. #include "iface.h"
  9. #include "config.h"
  10. #include "internet.h"
  11. #include "ip.h"
  12. #include "ax25.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "trace.h"
  16.  
  17. static struct mbuf * near slip_encode __ARGS((struct mbuf *bp));
  18. static struct mbuf * near slip_decode __ARGS((int dev,char c));
  19.  
  20. /* Slip level control structure */
  21. struct slip Slip[ASY_MAX];
  22.  
  23. /* Send routine for point-to-point slip
  24.  * This is a trivial function since there is no slip link-level header
  25.  */
  26. int
  27. slip_send(bp,iface,gateway,prec,del,tput,rel)
  28. struct mbuf *bp;    /* Buffer to send */
  29. struct iface *iface;    /* Pointer to interface control block */
  30. int32 gateway;        /* Ignored (SLIP is point-to-point) */
  31. int prec;
  32. int del;
  33. int tput;
  34. int rel;
  35. {
  36.     if(iface == NULLIF){
  37.         free_p(bp);
  38.         return -1;
  39.     }
  40.     return (*iface->raw)(iface,bp);
  41. }
  42.  
  43. /* Encode a packet in SLIP format */
  44. static struct mbuf * near
  45. slip_encode(bp)
  46. struct mbuf *bp;
  47. {
  48.     int c;
  49.  
  50.     /* Allocate output mbuf that's twice as long as the packet.
  51.      * This is a worst-case guess (consider a packet full of FR_ENDs!)
  52.      */
  53.     struct mbuf *lbp = ambufw((int16)(2*len_p(bp) + 2));
  54.     char *cp = lbp->data;
  55.  
  56.     /* Flush out any line garbage */
  57.     *cp++ = FR_END;
  58.  
  59.     /* Copy input to output, escaping special characters */
  60.     while((c = PULLCHAR(&bp)) != -1){
  61.         switch(c){
  62.         case FR_ESC:
  63.             *cp++ = FR_ESC;
  64.             *cp++ = T_FR_ESC;
  65.             break;
  66.         case FR_END:
  67.             *cp++ = FR_ESC;
  68.             *cp++ = T_FR_END;
  69.             break;
  70.         default:
  71.             *cp++ = c;
  72.         }
  73.     }
  74.     *cp++ = FR_END;
  75.     lbp->cnt = cp - lbp->data;
  76.     return lbp;
  77. }
  78.  
  79. /* Send a raw slip frame -- also trivial */
  80. int
  81. slip_raw(iface,bp)
  82. struct iface *iface;
  83. struct mbuf *bp;
  84. {
  85.     struct mbuf *bp1;
  86.  
  87.     dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
  88.  
  89.     if((bp1 = slip_encode(bp)) == NULLBUF){
  90.         free_p(bp);
  91.         return -1;
  92.     }
  93.     return Slip[iface->xdev].send(iface->dev,bp1);
  94. }
  95.  
  96. /* Process incoming bytes in SLIP format
  97.  * When a buffer is complete, return it; otherwise NULLBUF
  98.  */
  99. static struct mbuf * near
  100. slip_decode(dev,c)
  101. int dev;    /* Slip unit number */
  102. char c;        /* Incoming character */
  103. {
  104.     struct mbuf *bp;
  105.  
  106.     struct slip *sp = &Slip[dev];
  107.  
  108.     switch(uchar(c)){
  109.     case FR_END:
  110.         bp = sp->rbp;
  111.         sp->rbp = NULLBUF;
  112.         sp->rcnt = 0;
  113.         return bp;    /* Will be NULLBUF if empty frame */
  114.     case FR_ESC:
  115.         sp->escaped |= SLIP_FLAG;
  116.         return NULLBUF;
  117.     }
  118.  
  119.     if (sp->escaped & SLIP_FLAG) {
  120.         /* Translate 2-char escape sequence back to original char */
  121.         sp->escaped &= ~SLIP_FLAG;
  122.         switch(uchar(c)){
  123.         case T_FR_ESC:
  124.             c = FR_ESC;
  125.             break;
  126.         case T_FR_END:
  127.             c = FR_END;
  128.             break;
  129.         default:
  130.             sp->errors++;
  131.             break;
  132.         }
  133.     }
  134.  
  135.     /* We reach here with a character for the buffer;
  136.      * make sure there's space for it
  137.      */
  138.     if(sp->rbp == NULLBUF){
  139.         /* Allocate first mbuf for new packet */
  140.         sp->rbp1 = sp->rbp = ambufw(SLIP_ALLOC);
  141.         sp->rcp = sp->rbp->data;
  142.     } else if(sp->rbp1->cnt == SLIP_ALLOC){
  143.         /* Current mbuf is full; link in another */
  144.         sp->rbp1->next = ambufw(SLIP_ALLOC);
  145.         sp->rbp1 = sp->rbp1->next;
  146.         sp->rcp = sp->rbp1->data;
  147.     }
  148.     /* Store the character, increment fragment and total
  149.      * byte counts
  150.      */
  151.     *sp->rcp++ = c;
  152.     sp->rbp1->cnt++;
  153.     sp->rcnt++;
  154.     return NULLBUF;
  155. }
  156.  
  157. /* Process SLIP line input */
  158. void
  159. asy_rx(dev,p1,p2)
  160. int dev;
  161. void *p1;
  162. void *p2;
  163. {
  164.     int c;
  165.     struct mbuf *bp,*nbp;
  166.     struct phdr phdr;
  167.  
  168.     struct slip *sp = &Slip[dev];
  169.  
  170.     for(;;){
  171.         c = Slip[dev].get(Slip[dev].iface->dev);
  172.         if((bp = slip_decode(dev,(char)c)) == NULLBUF)
  173.             continue;    /* More to come */
  174.  
  175.         if((nbp = pushdown(bp,sizeof(phdr))) == NULLBUF){
  176.             free_p(bp);
  177.             continue;
  178.         }
  179.         phdr.iface = sp->iface;
  180.         phdr.type = sp->type;
  181.         memcpy(&nbp->data[0],(char *)&phdr,sizeof(phdr));
  182.         enqueue(&Hopper,nbp);
  183.     }
  184. }
  185.  
  186.